package com.dxf.sysadmin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dxf.common.utils.RedisUtil;
import com.dxf.common.utils.ResultJson;
import com.dxf.securitys.entity.SecurityUser;
import com.dxf.securitys.security.TokenManager;
import com.dxf.sysadmin.entity.SysRole;
import com.dxf.sysadmin.entity.SysUser;
import com.dxf.sysadmin.entity.UserRole;
import com.dxf.sysadmin.entity.po.SysUserPo;
import com.dxf.sysadmin.entity.qo.SysUserQo;
import com.dxf.sysadmin.mapper.SysUserMapper;
import com.dxf.sysadmin.mapper.UserRoleMapper;
import com.dxf.sysadmin.service.SysRoleService;
import com.dxf.sysadmin.service.SysUserService;
import com.dxf.sysadmin.service.UserRoleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.rmi.runtime.Log;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户表 服务实现类
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private BCryptPasswordEncoder encoder;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private TokenManager tokenManager;
    @Autowired
    private RedisUtil redisUtil;


    /**
     *更具用户id获取操作权限值
     */
    @Override
    public List<String> selectAuthorityByUserId(Long id) {
        return sysUserMapper.selectAuthorityByUserId(id);
    }

    /**
     *用户列表分页查询
     */
    @Override
    public ResultJson userPage(SysUserQo qry) {
        Page<SysUser> userPage = new Page<>(qry.getPage(), qry.getLimit());

        String likeName = qry.getName();
        LambdaQueryWrapper<SysUser> like=null;
        if (!StringUtils.isEmpty(likeName)){
            like = new QueryWrapper<SysUser>().lambda().like(SysUser::getName, qry.getName());
        }
        IPage<SysUser> userIPage = page(userPage, like);
        Map<String, Object> map = new HashMap<>();
        map.put("rows",userIPage.getRecords());
        map.put("total",userIPage.getTotal());
        return ResultJson.ok().data(map);
    }

    /**
     *更具id删除用户
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultJson deleteUser(List<Long> uidList) {
        removeByIds(uidList);
        userRoleService.removeByIds(uidList);
        return ResultJson.ok();
    }

    /**
     *新增或者更新用户
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultJson saveOrUpdate(SysUserPo po) {
        try {
            SysUser mo = new SysUser();
            BeanUtils.copyProperties(po,mo);
            if (po.getId()==null){
                //新增
                mo.setPassword(encoder.encode(mo.getPassword()));
            }
            //保存用户
            saveOrUpdate(mo);
            List<UserRole> list=new ArrayList<>();
            //保存用户角色关系
            po.getRoleList().forEach(x->{
                UserRole userRole = new UserRole();
                userRole.setUserId(mo.getId());
                userRole.setRoleId(x.longValue());
                //不包含才添加
                if (!list.contains(userRole)){
                    list.add(userRole);
                }
            });
            if (po.getId()==null){
                //新增
                userRoleService.saveBatch(list);
            }else {
                //修改
                userRoleService.removeById(po.getId());
                userRoleService.saveBatch(list);
            }
            return ResultJson.ok();
        }catch (Exception e){
            e.printStackTrace();
            return ResultJson.error();
        }
    }

    /**
     *获取对象和角色关系详情
     */
    @Override
    public ResultJson details(Long uid) {
        try {
            //查询用户对象
            SysUser byId = getById(uid);
            //生成并复制对象属性
            SysUserPo sysUserPo = new SysUserPo();
            BeanUtils.copyProperties(byId,sysUserPo);
            //获取用户角色关系
            List<UserRole> list = userRoleService.
                    list(new QueryWrapper<UserRole>().
                            lambda().eq(UserRole::getUserId, uid));
            //获取多个对象的某个属性返回集合
            List<Long> collect = list.stream().map(UserRole::getRoleId).collect(Collectors.toList());
            //保存角色id集合
            sysUserPo.setRoleList(collect);

            //保存所有角色
            List<SysRole> list1 = sysRoleService.list();
            sysUserPo.setSysRoles(list1);
            return ResultJson.ok().data("sysUserPo",sysUserPo);
        }catch (Exception e){
            return ResultJson.error();
        }
    }

    /**
     *获取所有角色
     */
    @Override
    public ResultJson getRoles() {
        return ResultJson.ok().data("Roles",sysRoleService.list());
    }

    /**
     *重置密码
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultJson resetPWD(Long id) {
        String password = UUID.randomUUID().toString().replace("-", "").substring(0, 6);
        String encode = encoder.encode(password);
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        sysUser.setPassword(encode);
        updateById(sysUser);
        return ResultJson.ok().data("password",password);
    }

    /**
     *更具token获取角色信息
     */
    @Override
    public ResultJson getInfo(String token) {
        String userName = tokenManager.getUserFromToken(token);
        SecurityUser user = (SecurityUser) redisUtil.get(userName);
        return ResultJson.ok().data("user",user.getCurrentUserInfo());
    }
}